var express = require('express');
var crypto = require('crypto');
var NodeRSA = require('node-rsa');
var router = express.Router();

router.post('/md5Simple', function (req, res, next) {
    var psd = 'zxw68824';
    var md5 = crypto.createHash('md5');
    md5.update(psd);
    var stringSign = md5.digest('hex');
    var sign = stringSign.toLocaleLowerCase();

    console.log({
        接口注释: 'MD5加密--简单版直接加密',
        运行时间: new Date(),
        原密码: psd,
        加密后的密码: sign
    });

    res.send(sign);
});

router.post('/md5Normal', function (req, res, next) {
    var account = 'zhangsan';
    var psd = 'zxw68824';
    var type = 1;
    var param = {
        account: account,
        psd: psd,
        type: type,
        time: new Date().getTime()
    }

    var param1 = createSign({
        account: account,
        psd: psd,
        type: type,
        time: new Date().getTime()
    }, 'asdfghjkl123456');

    console.log({
        接口注释: 'MD5加密--结合指定算法进行加密',
        运行时间: new Date(),
        未加密的参数: param,
        加密后的参数: param1
    });

    res.send(param1.sign);
});

router.post('/sha1_simple', function (req, res, next) {
    var psd = 'zxw68824';
    var sha1 = crypto.createHash('sha1');
    sha1.update(psd);
    var d = sha1.digest('hex');

    console.log({
        接口注释: 'SHA-1加密--简单加密',
        运行时间: new Date(),
        未加密的密码: psd,
        加密后的参数: d
    });

    res.send(d);
});

router.post('/EncryptDES', function (req, res, next) {
    var psd = 'zxw68824';
    var buffer = new Buffer(psd);
    var key = new Buffer('12345670');
    var iv = new Buffer('11112222');
    var cipher = crypto.createCipheriv('des-cbc', key, iv);
    cipher.setAutoPadding(true);
    var ciph = cipher.update(buffer, 'utf8', 'base64');
    ciph += cipher.final('base64');

    console.log({
        接口注释: 'DES加密--简单加密',
        运行时间: new Date(),
        未加密的密码: psd,
        加密后的参数: ciph
    });

    res.send(ciph);
});

router.post('/DecryptDES', function (req, res, next) {
    var psd = '6AM0CmI64i+MKO9V/fQxNA==';
    var key = new Buffer('12345670');
    var iv = new Buffer('11112222');
    var decipher = crypto.createDecipheriv('des-cbc', key, iv);
    decipher.setAutoPadding(true);
    var txt = decipher.update(psd, 'base64', 'utf8');
    txt += decipher.final('utf8');

    console.log({
        接口注释: 'DES解密',
        运行时间: new Date(),
        未解密的密码: psd,
        解密后的参数: txt
    });

    res.send(txt);
});

router.post('/Decrypt3DES', function (req, res, next) {
    var key = new Buffer('0123456789abcd0123456789');
    var iv = new Buffer('12345678');
    var plaintext = 'zxw68824';
    var alg = 'des-ede3-cbc';

    //加密 
    var cipher = crypto.createCipheriv(alg, key, iv);
    var ciph = cipher.update(plaintext, 'utf8', 'hex');
    ciph += cipher.final('hex');

    console.log({
        接口注释: '3DES加密',
        运行时间: new Date(),
        加密后的密码: ciph
    });

    //解密 
    var decipher = crypto.createDecipheriv(alg, key, iv);
    var txt = decipher.update(ciph, 'hex', 'utf8');
    txt += decipher.final('utf8');

    console.log({
        接口注释: '3DES解密',
        运行时间: new Date(),
        解密后的参数: txt
    });

    res.send(txt);
});

router.post('/AES_simple', function (req, res, next) {
    let key = 'llc2019050920aok';
    let iv = '1983457286157286';

    //加密
    var cipherChunks = [];
    var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);
    cipher.setAutoPadding(true);
    cipherChunks.push(cipher.update('zxw68824', 'utf8', 'base64'));
    cipherChunks.push(cipher.final('base64'));
    var txt = cipherChunks.join('');

    //解密
    var cipherChunks = [];
    var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv);
    decipher.setAutoPadding(true);
    cipherChunks.push(decipher.update('CXmc/eUyd1iYipXI2t51Sg==', 'base64', 'utf8'));
    cipherChunks.push(decipher.final('utf8'));
    var result = cipherChunks.join('');

    console.log({
        接口注释: 'RSA加密',
        运行时间: new Date(),
        原参数: 'zxw68824',
        加密后的参数: txt,
        解密后的参数: result
    });

    res.send(txt);
});

router.post('/RSA_verify', function (req, res, next) {
    var key = new NodeRSA({
        b: 1024
    });

    //私钥签名
    var priKey = new NodeRSA(key.exportKey('pkcs8-private'), 'pkcs8-private');
    var signature = priKey.sign('zxw68824');

    //公钥验证
    var pubKey = new NodeRSA(key.exportKey('pkcs8-public'), 'pkcs8-public');
    var flag = pubKey.verify('zxw68824', signature);

    console.log({
        接口注释: 'AES加密',
        运行时间: new Date(),
        原参数: 'zxw68824',
        私钥签名: signature,
        公钥验证: flag
    });

    res.send(signature);
});

router.post('/RSA_simple', function (req, res, next) {
    var key = new NodeRSA({
        b: 1024
    });

    //公钥加密
    var pubKey = new NodeRSA(key.exportKey('pkcs8-public'), 'pkcs8-public');
    var encrypted = pubKey.encrypt('zxw68824', 'base64');

    //私钥解密
    var priKey = new NodeRSA(key.exportKey('pkcs8-private'), 'pkcs8-private');
    var decrypted = priKey.decrypt(encrypted, 'utf8');
    console.log(decrypted);

    console.log({
        接口注释: 'AES加密',
        运行时间: new Date(),
        原参数: 'zxw68824',
        加密后的参数: encrypted,
        解密后的参数: decrypted
    });

    res.send(encrypted);
});

//返回拼接上sign的请求对象
var createSign = this.createSign = function (obj, secret) {
    var sortArrStr = getSortStrByAsciiWithObj(obj);

    var waitSecretStr = secret + sortArrStr + secret;
    var md5 = crypto.createHash('md5');
    md5.update(waitSecretStr);
    var stringSign = md5.digest('hex');
    var sign = stringSign.toLocaleLowerCase();
    obj.sign = sign;
    return obj;
}

//构造按Ascii码顺序组成的字符串
function getSortStrByAsciiWithObj(obj) {
    var arr = [];
    for (var key in obj) {
        arr.push(key);
    }
    var sortArr = getsParaFromArr(arr);
    var sortArrStr = '';
    sortArr.forEach(function (key) {
        var item = {};
        item[key] = obj[key];
        sortArrStr += key + '=' + obj[key];
    });

    return sortArrStr;
}

//传入数组，返回按Ascii码排序的数组
function getsParaFromArr(sParaTemp) {
    var sPara = [];
    //除去数组中的空值和签名参数
    for (var i1 = 0; i1 < sParaTemp.length; i1++) {
        var value = sParaTemp[i1];
        if (value == null || value == "" || value == "sign") {
            continue;
        }
        sPara.push(value);
    }
    sPara = sPara.sort();
    return sPara;
}

module.exports = router;